home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / pctchnqs / 1990 / number6 / l1.asm < prev    next >
Assembly Source File  |  1990-11-14  |  4KB  |  93 lines

  1. ; Searches a text buffer for a text string. Uses REPNZ SCASB to scan
  2. ; the buffer for locations that match the first character of the
  3. ; searched-for string, then uses REPZ CMPS to check fully only those
  4. ; locations that REPNZ SCASB has identified as potential matches.
  5. ;
  6. ; Adapted from Zen of Assembly Language, by Michael Abrash
  7. ;
  8. ; C small model-callable as:
  9. ;    unsigned char * FindString(unsigned char * Buffer,
  10. ;        unsigned int BufferLength, unsigned char * SearchString,
  11. ;    unsigned int SearchStringLength);
  12. ;
  13. ; Returns a pointer to the first match for SearchString in Buffer, or
  14. ; a NULL pointer if no match is found. Buffer should not start at
  15. ; offset 0 in the data segment to avoid confusing a match at 0 with
  16. ; no match found.
  17.  
  18. Parms    struc
  19.         dw    2 dup(?) ;pushed BP/return address
  20. Buffer        dw    ?    ;pointer to buffer to search
  21. BufferLength    dw    ?    ;length of buffer to search
  22. SearchString    dw    ?    ;pointer to string for which to search
  23. SearchStringLength dw    ?    ;length of string for which to search
  24. Parms    ends
  25.     .model    small
  26.     .code
  27.     public _FindString
  28. _FindString    proc    near
  29.     push    bp    ;preserve caller's stack frame
  30.     mov    bp,sp    ;point to our stack frame
  31.     push    si    ;preserve caller's register variables
  32.     push    di
  33.     cld        ;make string instructions increment pointers
  34.     mov    si,[bp+SearchString] ;pointer to string to search for
  35.     mov    bx,[bp+SearchStringLength] ;length of string
  36.     and    bx,bx
  37.     jz    FindStringNotFound ;no match if string is 0 length
  38.     mov    dx,[bp+BufferLength] ;length of buffer
  39.     sub    dx,bx    ;difference between buffer and string lengths
  40.     jc    FindStringNotFound ;no match if search string is
  41.             ; longer than buffer
  42.     inc    dx    ;difference between buffer and search string
  43.             ; lengths, plus 1 (# of possible string start
  44.             ; locations to check in the buffer)
  45.     mov    di,ds
  46.     mov    es,di
  47.     mov    di,[bp+Buffer] ;point ES:DI to buffer to search thru
  48.     lodsb        ;put the first byte of the search string in AL
  49.     mov    bp,si    ;set aside pointer to the second search byte
  50.     dec    bx    ;don't need to compare the first byte of the
  51.             ; string with CMPS; we'll do it with SCAS
  52. FindStringLoop:
  53.     mov    cx,dx    ;put remaining buffer search length in CX
  54.     repnz    scasb    ;scan for the first byte of the string
  55.     jnz    FindStringNotFound ;not found, so there's no match
  56.             ;found, so we have a potential match-check the
  57.             ; rest of this candidate location
  58.     push    di    ;remember the address of the next byte to scan
  59.     mov    dx,cx    ;set aside the remaining length to search in
  60.             ; the buffer
  61.     mov    si,bp    ;point to the rest of the search string
  62.     mov    cx,bx    ;string length (minus first byte)
  63.     shr    cx,1    ;convert to word for faster search
  64.     jnc    FindStringWord ;do word search if no odd byte
  65.     cmpsb        ;compare the odd byte
  66.     jnz    FindStringNoMatch ;odd byte doesn't match, so we
  67.             ; haven't found the search string here
  68. FindStringWord:
  69.     jcxz    FindStringFound ;test whether we've already checked
  70.             ; the whole string; if so, this is a match
  71.             ; bytes long; if so, we've found a match
  72.     repz    cmpsw    ;check the rest of the string a word at a time
  73.     jz    FindStringFound ;it's a match
  74. FindStringNoMatch:
  75.     pop    di    ;get back pointer to the next byte to scan
  76.     and    dx,dx    ;is there anything left to check?
  77.     jnz    FindStringLoop ;yes-check next byte
  78. FindStringNotFound:
  79.     sub    ax,ax    ;return a NULL pointer indicating that the
  80.     jmp    FindStringDone ; string was not found
  81. FindStringFound:
  82.     pop    ax    ;point to the buffer location at which the
  83.     dec    ax    ; string was found (earlier we pushed the
  84.             ; address of the byte after the start of the
  85.             ; potential match)
  86. FindStringDone:
  87.     pop    di    ;restore caller's register variables
  88.     pop    si
  89.     pop    bp    ;restore caller's stack frame
  90.     ret
  91. _FindString    endp
  92.     end
  93.